import $ from 'jquery';
import { drawLoop } from '../../utils/loop';
import { setStyle, sleep } from '../../utils/other';

const canvas = document.createElement("canvas");
const core = canvas.getContext('2d');
const list = [];

function loadFonts() {
    for (let x of ['rzzyt', 'zkxw']) {
        let y = new FontFace(x, `url(/font/${x}.woff)`)
        y.load().then(font => {
            document.fonts.add(font)
        });
    }
};

function resize() {
    canvas.width = $(window).width();
    canvas.height = $(window).height();
};

function initCanvas() {
    setStyle(canvas, {
        position: "fixed",
        top: "0",
        left: "0",
        zIndex: "-2",
        pointerEvents: "none",
        letterSpacing: "25px"
    });
    $(window).on("resize", resize);
    resize();
    document.body.append(canvas);
};

function draw() {
    core.clearRect(0, 0, $(window).width(), $(window).height());


    for (let opt of list) {
        if (opt == null || opt.del) {
            list.splice(list.indexOf(opt), 1);
        };
    };

    for (let opt of list) {
        if (!(opt == null || opt.del)) {
            switch (opt.type) {
                case "fadeOutText":
                    core.beginPath();
                    core.font = `${opt.fontSize}px ${opt.fontFamily}`;
                    core.textAlign = "center";
                    core.textBaseline = "top";
                    core.fillStyle = "#fff";
                    core.globalAlpha = 1;
                    canvas.style.letterSpacing = "25px";
                    core.fillText(opt.text, opt.x, opt.y);

                    var width = core.measureText(opt.text).width;

                    core.fillStyle = "#000";
                    if (opt.maskPosition == "right") {
                        core.fillRect(
                            (opt.x - width / 2) + width * (opt.mask / 100),
                            opt.y - 10,
                            width - width * (opt.mask / 100),
                            opt.fontSize + 12
                        );
                    } else if (opt.maskPosition == "left") {
                        core.fillRect(
                            opt.x - width / 2,
                            opt.y - 10,
                            width * (opt.mask / 100),
                            opt.fontSize + 12
                        );
                    }
                    core.closePath();

                    break;
                case "fadingText":
                    core.beginPath();
                    core.font = `${opt.fontSize}px ${opt.fontFamily}`;
                    core.textAlign = "center";
                    core.textBaseline = "top";
                    core.strokeStyle = "#fff";
                    core.globalAlpha = opt.opac;
                    core.setLineDash([2]);
                    canvas.style.letterSpacing = "20px";
                    core.strokeText(opt.text, opt.x, opt.y);
                    core.closePath();
                    break;
                case "spaceFadingText":
                    core.beginPath();
                    core.font = `${opt.fontSize}px ${opt.fontFamily}`;
                    core.textAlign = "center";
                    core.textBaseline = "top";
                    core.fillStyle = "#fff";
                    core.globalAlpha = opt.opac;
                    canvas.style.letterSpacing = String(opt.letterSpacing) + "px";
                    core.fillText(opt.text, opt.x, opt.y);
                    core.closePath();
                    break;
            }
        };
    };
}

function getY() {
    return $(window).height() / 2 - ($(window).height() * 0.25 + 121) / 2;
}

function leftRightFadeOutText(text) {
    const config = {
        type: "fadeOutText",
        text,
        x: $(window).width() / 2,
        y: getY(),
        fontSize: 70,
        fontFamily: "sans-serif",
        mask: 100,
        maskPosition: "right"
    };

    list.push(config);

    const exp = {
        show() {
            !async function () {
                config.mask = 0;
                config.maskPosition = "right";
                var a1 = 0;
                var a2 = 100;
                while (!(Math.abs(a2 - a1) < 1)) {
                    a1 += (a2 - a1) / 6;
                    config.mask = a1;
                    await sleep(1000 / 60);
                };
                config.mask = a2;
            }();
            return exp;
        },
        hide(afterRemove = false) {
            !async function () {
                config.mask = 0;
                config.maskPosition = "left";
                var a1 = 0;
                var a2 = 100;
                while (!(Math.abs(a2 - a1) < 1)) {
                    a1 += (a2 - a1) / 6;
                    config.mask = a1;
                    await sleep(1000 / 60);
                };
                config.mask = a2;
                if (afterRemove) config.del = true;
            }();
            return exp;
        },
        remove() {
            config.del = true;
            return exp;
        }
    };
    return exp;
};

function fadingText(text) {
    const config = {
        type: "fadingText",
        text,
        x: $(window).width() / 2,
        y: getY(),
        fontSize: 70,
        fontFamily: "rzzyt",
        opac: 0
    };

    list.push(config);

    const exp = {
        show() {
            !async function () {
                var a1 = 0;
                var a2 = 1;
                while (!(Math.abs(a2 - a1) < 0.001)) {
                    a1 += (a2 - a1) / 4;
                    config.opac = a1;
                    await sleep(1000 / 60);
                };
                config.opac = a2;
            }();
            return exp;
        },
        hide(afterRemove = false) {
            !async function () {
                var a1 = 1;
                var a2 = 0;
                while (!(Math.abs(a2 - a1) < 0.001)) {
                    a1 += (a2 - a1) / 4;
                    config.opac = a1;
                    await sleep(1000 / 60);
                };
                config.opac = a2;
                if (afterRemove) config.del = true;
            }();
            return exp;
        },
        remove() {
            config.del = true;
            return exp;
        }
    };
    return exp;
}

function spaceFadingText(text) {
    canvas.style.letterSpacing = 50;
    const config = {
        type: "spaceFadingText",
        text,
        x: $(window).width() / 2,
        y: getY(),
        fontSize: 65,
        fontFamily: "zkxw",
        opac: 0,
        letterSpacing: 50
    };

    list.push(config);

    const exp = {
        show() {
            !async function () {
                var a1 = 0;
                var a2 = 1;
                var a3 = 50;
                var a4 = 20;
                while (!((Math.abs(a2 - a1) < 0.001) && Math.abs(a4 - a3) < 1)) {
                    a1 += (a2 - a1) / 6;
                    a3 += (a4 - a3) / 5;
                    config.opac = a1;
                    config.letterSpacing = a3;
                    await sleep(1000 / 60);
                };
                config.opac = a2;
                config.letterSpacing = a4;
            }();
            return exp;
        },
        hide(afterRemove = false) {
            !async function () {
                var a1 = 1;
                var a2 = 0;
                var a3 = 20;
                var a4 = 0;
                while (!((Math.abs(a2 - a1) < 0.001) && Math.abs(a4 - a3) < 1)) {
                    a1 += (a2 - a1) / 6;
                    a3 += (a4 - a3) / 5;
                    config.opac = a1;
                    config.letterSpacing = a3;
                    await sleep(1000 / 60);
                };
                config.opac = a2;
                config.letterSpacing = 25;
                if (afterRemove) config.del = true;
            }();
            return exp;
        },
        remove() {
            config.del = true;
            return exp;
        }
    };
    return exp;
}

function init() {
    loadFonts();
    initCanvas();
    drawLoop(draw);
};

export { init, leftRightFadeOutText, fadingText, spaceFadingText };